package tools;

import java.util.Collection;

import coreModel.HIT;

import reports.builders.TestBuilder;
import reports.directors.ProductStatisticsReport;
import reports.directors.ProductStatsGenerator;

import org.junit.*;

public class Tester
{
	public static int END_DAY = 2;
	public static int END_MONTH = 4;
	public static int END_YEAR = 2012;
	public static int REPORT_LEN = 1; // period of report in months
	
	private boolean success;
	private String errors;
	
	public Tester(String input_xml, String oracle_html)
	{	
		errors = "";
		success = false;
		
		initializeModel(input_xml);
		TestBuilder actual = initializeBuilder();
		HTMLParser oracle = new HTMLParser(oracle_html);
		
		compareReports(actual, oracle);
		
		
	}

	private void compareReports(TestBuilder actual, HTMLParser oracle)
	{
		success = true;
		
		Assert.assertTrue( actual.getRowCount() == oracle.getRowCount() );
		
		for (int row=0; row<actual.getRowCount(); row++)
		{
			boolean row_success = true;
			String err_cols = "";
			
			Assert.assertTrue( actual.getRow(row).size() ==  oracle.getRow(row).size());
			for (int col=0; col<actual.getRow(row).size(); col++)
			{
				String act_val = actual.getCell(row, col).toLowerCase();
				String orc_val = oracle.getCell(row, col).toLowerCase();
				
				if ( !act_val.equals(orc_val) )
				{
					success = false;
					row_success = false;
					err_cols = err_cols + "  " + (col + 1);
				}
				
			}
			
			if (!row_success)
			{
				errors = errors + composeError(row, actual, oracle);
				errors = errors + "\nSee Columns:" + err_cols;
			}
			
		}
		
		
	}
	
	private String composeError(int row, TestBuilder actual, HTMLParser oracle)
	{
		String header =       "Header:   " + listToString(actual.getTableHeader());
		String expected =   "\nExpected: " + listToString( oracle.getRow(row) );
		String actual_val = "\nActual:   " + listToString( actual.getRow(row) );
		
		return header + expected + actual_val;
	}
	
	
	
	private String listToString(Collection<String> list)
	{
		String result = "";
		
		for (String tmp : list)
			result = result + "\t\t" + tmp;
		
		return result;
	}

	private TestBuilder initializeBuilder()
	{
		ProductStatsGenerator.setEndDate(END_DAY, END_MONTH, END_YEAR);
		ProductStatisticsReport PStats = new ProductStatisticsReport(REPORT_LEN);
		TestBuilder report_builder = new TestBuilder();
		PStats.build(report_builder);
		
		return report_builder;
	}

	private void initializeModel(String input_xml)
	{
		HIT.setInstance(null);
		Importer.reInitialize();
		
		String [] input = {input_xml};
		Importer.main( input );
		
		HIT.getInstance().load();
	}

	public boolean success()
	{
		return success;
	}

	public void displayErrors()
	{
		System.out.println(errors);
	}
	
	
}
